using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Microsoft.VSPowerToys.PackInstallerDataModel;

namespace Microsoft.VSPowerToys.PackInstaller
{
    public partial class TagAndFilterControl : UserControl
    {
        public event EventHandler<SearchTextChangedEventArgs> SearchTextChanged;
        public event EventHandler<TagSelectedEventArgs> TagSelectionChanged;

        /// <summary>
        /// Raised when user changes the sort order
        /// </summary>
        public event EventHandler<SortMethodSelectedEventArgs> SortOrderChanged
        {
            add { this.sortListControl.SortMethodSelected += value; }
            remove { this.sortListControl.SortMethodSelected -= value; }
        }

        /// <summary>
        /// Gets the sort order user has selected
        /// </summary>
        public SortOrder SortOrder
        {
            get { return this.sortListControl.CurrentSortOrder; }
        }

        private int displayedCount;
        private int totalCount;

        /// <summary>
        /// Gets or sets the current number of items displayed to user
        /// </summary>
        public int DisplayedItemCount
        {
            get { return this.displayedCount; }
            set
            {
                this.displayedCount = value;
                this.displayCountLabel.Text = this.displayedCount + "/" + this.totalCount;
            }
        }

        /// <summary>
        /// Gets or sets the total number of items available
        /// </summary>
        public int TotalItemCount
        {
            get { return this.totalCount; }
            set
            {
                this.totalCount = value;
                this.showAllTagItemControl.TagCount = value;
                this.displayCountLabel.Text = this.displayedCount + "/" + this.totalCount;
            }
        }

        public ToolItem.SortByField SelectedSortMethod
        {
            get { return this.sortListControl.CurrentlySelectedSortMethod; }
        }

        /// <summary>
        /// Gets the tag selected by the user
        /// </summary>
        public string SelectedTag
        {
            get { return this.tagListControl.CurrentlySelectedTag; }
        }

        /// <summary>
        /// Gets the text user has typed in to search box
        /// </summary>
        public string SearchText
        {
            get { return this.typeAlongSearchTextBox.Text; }
        }

        /// <summary>
        /// Constructor, sets up the fonts and initializes the All tag.
        /// </summary>
        public TagAndFilterControl()
        {
            InitializeComponent();
            this.Font = SystemFonts.DialogFont;
            this.displayingLabel.Font = new Font(SystemFonts.DialogFont, FontStyle.Bold);
            this.sortByLabel.Font = new Font(SystemFonts.DialogFont, FontStyle.Bold);
            this.filterByLabel.Font = new Font(SystemFonts.DialogFont, FontStyle.Bold);

            this.showAllTagItemControl.TagName = Strings.AllTagName;
            this.showAllTagItemControl.CurrentTagState = TagItemControl.TagState.Selected;
        }

        /// <summary>
        /// Clears the current set of tags and creates the new one.
        /// </summary>
        public void BuildTagList(Collection<string> tags)
        {
            this.tagListControl.ClearTags();
            this.tagListControl.AddTags(tags);
            this.tagListControl.Refresh();
        }

        /// <summary>
        /// Updates the sort field list
        /// </summary>
        /// <param name="fields"></param>
        public void UpdateSortList(Dictionary<string, ToolItem.SortByField> fields)
        {
            this.sortListControl.AddSortMethods(fields);
        }

        public void SetSortMethod(ToolItem.SortByField whichMethod, SortOrder whatOrder)
        {
            this.sortListControl.SetSortMethod(whichMethod, whatOrder);
        }

        /// <summary>
        /// Event triggered when a new tag is selected.  We want to clear the All tag's selection, and 
        /// retrigger the event for anyone else listening.
        /// </summary>
        /// <param name="sender" />
        /// <param name="e" />
        private void tagListControl_TagSelected(object sender, TagSelectedEventArgs e)
        {
            if (this.showAllTagItemControl.CurrentTagState != TagItemControl.TagState.None)
            {
                this.showAllTagItemControl.CurrentTagState = TagItemControl.TagState.None;
            }

            if (this.TagSelectionChanged != null)
            {
                this.TagSelectionChanged(this, e);
            }
        }

        /// <summary>
        /// Event triggered when the user types in the search box.
        /// The actual searching is handled by another control so we need to 
        /// relay this message back up the chain.
        /// </summary>
        /// <param name="sender" />
        /// <param name="e" />
        private void typeAlongSearchTextBox_TextChanged(object sender, EventArgs e)
        {
            if(this.SearchTextChanged != null)
            {
                this.SearchTextChanged(this, new SearchTextChangedEventArgs(this.typeAlongSearchTextBox.Text));
            }
        }

        /// <summary>
        /// Event triggered when the user selects the All tag.
        /// We want to clear out the selection in the tag list, and get the list of packs updated.
        /// </summary>
        /// <param name="sender" />
        /// <param name="e" />
        private void showAllTagItemControl_TagSelected(object sender, TagSelectedEventArgs e)
        {
            typeAlongSearchTextBox.Text = string.Empty;
            this.tagListControl.ClearTagSelection();
         

            if (this.TagSelectionChanged != null)
            {
                this.TagSelectionChanged(this, new TagSelectedEventArgs(string.Empty));
            }
        }

        /// <summary>
        /// Clears the search box and sets the tag state to the All tag.
        /// We don't want to call the SelectTag method because we don't want
        /// to have a bunch of extra refreshes going on.
        /// </summary>
        public void ResetTagAndFilter()
        {
            typeAlongSearchTextBox.Text = string.Empty;
            this.tagListControl.ClearTagSelection();
            this.showAllTagItemControl.CurrentTagState = TagItemControl.TagState.Selected;
        }
    }

    public class SearchTextChangedEventArgs: EventArgs
    {
        [NonSerialized]
        private string searchText;

        public string SearchText
        {
            get { return this.searchText; }
            set { this.searchText = value; }
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="task">Task that owns the event</param>
        public SearchTextChangedEventArgs(string searchText)
        {
            this.searchText = searchText;
        }
    }
}
